import { UnknownError } from '@livestore/common'
import { Effect, Exit } from '@livestore/utils/effect'
import { expect, test } from '@playwright/test'

import { runAndGetExit, runTest } from './shared-test.ts'
import * as Bridge from './unit-tests/bridge.ts'

const modulePrefix = '../unit-tests'

test(
  'bootstatus',
  runTest(
    Effect.gen(function* () {
      const exit = yield* runAndGetExit({
        importPath: `${modulePrefix}/bootstatus.ts`,
        exportName: 'test',
        schema: Bridge.ResultBootStatus,
      })

      expect(exit).toStrictEqual(
        Exit.succeed({
          bootStatusUpdates: [
            { stage: 'loading' },
            { stage: 'migrating', progress: { done: 1, total: 1 } },
            { stage: 'done' },
          ],
          migrationsReport: {
            migrations: [{ tableName: 'todos', hashes: { expected: -35_462_037_457, actual: undefined } }],
          },
        }),
      )
    }),
  ),
)

test(
  'store-boot-error',
  runTest(
    Effect.gen(function* () {
      const exit = yield* runAndGetExit({
        importPath: `${modulePrefix}/store-boot-error.ts`,
        exportName: 'test',
        schema: Bridge.ResultStoreBootError,
      })

      expect(exit).toStrictEqual(
        Exit.fail(UnknownError.make({ cause: new Error('Boom!', { cause: { name: 'Error', message: 'Boom!' } }) })),
      )
    }),
  ),
)

test(
  'schema-migration',
  runTest(
    Effect.gen(function* () {
      const exit = yield* runAndGetExit({
        importPath: `${modulePrefix}/schema-migration/index.ts`,
        exportName: 'testMultipleMigrations',
        schema: Bridge.ResultMultipleMigrations,
      })

      expect(exit._tag).toBe('Success')
      if (exit._tag !== 'Success') throw new Error(`Expected success exit, received ${exit._tag}`)

      const { migrationsCount, archivedStateDbFiles } = exit.value

      // Verify that after 22 migrations, we can still complete the process without running out of file handles
      // See packages/@livestore/sqlite-wasm/src/browser/opfs/AccessHandlePoolVFS.ts for default file handle pool size
      expect(migrationsCount).toBe(22)

      // Verify that we have 3 archived state DB files
      // See packages/@livestore/adapter-web/src/web-worker/common/persisted-sqlite.ts for default retention count
      expect(archivedStateDbFiles.length).toBe(3)

      // Verify that each archived file isn’t empty
      archivedStateDbFiles.forEach((file) => {
        expect(file.size).toBeGreaterThan(0)
      })
    }),
  ),
)
